var TAG_SEARCH_URL = baseurl + "/tag_search.php";
var TAG_USER_SAVE_URL = baseurl + 'save_user_tags.php';
var TIMEOUT_ATTR = "timeout";
var PREVIOUS_SEARCH_ATTR = "previous_search"

// setup all AJAXs
$.ajaxSetup({
	type: "post",
	beforeSend: function(){
			$('.throbber').animate({top:0});
	},
	complete: function(){
		$('.throbber').animate({top:-33});
	}
});

// on body click remove tag-searches
$(document.body).click(function(e){
	if(e.target.nodeName.toLowerCase()!="a"){
		$(".tags-search-container").remove();
	}
});

/**
 * Generate random Unique Identifier
 */
function _UUID(){
	var buffer = "0123456798qwertyuiopasdfghjklzxcvbnm";
	var ret = "";
	for(var i=0; i<10; i++){
		ret += buffer.substr(Math.floor(Math.random()*buffer.length), 1);
	}
	return ret;
}

/**
 * Initialize auto-search inputs
 * Based on type, different dialogs are shown
 * @param String jQuery-Expression
 * @param String TagBox-Type
 * @param Function Call on Tag-Result click
 */
function InitTagsBox(expr, type, func){
	// Tags Search
	$(expr).attr("uuid", _UUID());
	$(expr).keyup(function(e){
		var element = $(this);
		var prev_search = element.attr(PREVIOUS_SEARCH_ATTR);
		var to = element.attr(TIMEOUT_ATTR);
		if(to){
			clearTimeout(to);
		}
		
		var val = element.val().replace(/^[\s\r\t\n]+|[\s\r\n\t]+$/g, "");
		var to = e.keyCode==13 ? 0 : 600;
		if(val.length < 3 || (val == prev_search && to>0)){
			return;
		}
		element.attr(TIMEOUT_ATTR, setTimeout(function(){
			TagsSearch(element, type, func);
		}, to));
	});
	
	$(expr).keydown(function(){
		var to = $(this).attr(TIMEOUT_ATTR);
		if(to){
			clearTimeout(to);
		}
	});
	
	var btnSubmit = $('<a href="javascript:void(0)" class="tags-search-submit" target="'+expr+'"></a>');
	$(expr).after(btnSubmit)
	btnSubmit.click(function(){
		TagsSearch($($(this).attr("target")), type, func);
		return false;
	});
}

/**
 * Do the Tag Search
 * @param Object jQuery Object
 * @param String TagBox-Type
 * @param Function Call on Tag-Result click
 */
function TagsSearch(element, type, func){
	if(!element.length){
		return;
	}
	var val = element.val();
	element.attr(PREVIOUS_SEARCH_ATTR, val);
	$.ajax({
		url: TAG_SEARCH_URL,
		data: {keyword: val},
		beforeSend: function(){
			element.addClass('loading');
		},
		complete: function(req){
			element.removeClass('loading');
			if(req.status==200){
				var data = eval('('+req.responseText+')');
				switch(type){
					/**
					 * display tabbed dropdown below the element (input)
					 */ 
					default:
						TagsDialogBox(element, data, true, func);
				}
			}
		}
	});
}

/**
 * Draw the Tags Dialog
 * @param Object jQuery Object
 * @param JSON Tags received from Response
 * @param Bool hasTabs?
 * @param Function Call on Tag-Result click
 */
function TagsDialogBox(element, data, tabbed, func){
	tabbed = tabbed ? true : false;
	var div = $("#tags-search-"+element.attr("uuid"));
	if(!data.length){
		div.remove();
		return;
	}

	
	if(!div.length){
		div = $('<div id="tags-search-'+element.attr("uuid")+'" class="tags-search-container tags-container" />');
		if(element){
			var pos = element.position();
			div.css({
				left: pos.left,
				top: pos.top + element.height()
			});
			element.parent().append(div);
		}else{
			div.dialog({
				modal: true,
				width: 600,
				height: 400,
				title: "Tags"
			});
		}
	}
	div.draggable({
		handle: ".tabs"
	});
	div.empty();
	
	if(tabbed){
		div.append('<div class="tabs"><a href="javascript:void(0)" onclick="$(this).parent().parent().remove()" class="close">X</a><a href="#subject" class="tab subject">Subject</a><a href="#people" class="tab people">People</a><a href="#geo" class="tab geo">Geo</a></div>');
		div.append('<div class="content subject" />');
		div.append('<div class="content people" />');
		div.append('<div class="content geo" />');
	}else{
		div.append('<div class="subject geo people" />');
	}
	
	div.find("a.tab").click(function(){
		var target = $(this).attr("href").replace(/^\#/, "");
		div.find("a.tab").removeClass("active");
		div.find(".content").removeClass("visible");
		
		div.find("a.tab."+target).addClass("active");
		div.find(".content."+target).addClass("visible");
	});
	
	var types = [];
	for(i in data){
		a = $('<a href="javascript:void(0)" class="tag_box" id="searchtag-'+data[i].type+'-'+data[i].id+'">'+data[i].name+'</a>');
		a.click(function(){
			func($(this));
		});
		if(types.indexOf(data[i].type) < 0){
			types.push(data[i].type);
		}
		div.find("div."+data[i].type).append(a);
	}
	
	var all_types = ["subject","people","geo"];
	div.find(".tab").removeClass("active");
	div.find(".content").removeClass("visible");
	div.find(".tab."+types[0]).addClass("active");
	div.find(".content."+types[0]).addClass("visible")
	for(var i=0; i<all_types.length; i++){
		if(types.indexOf(all_types[i]) < 0){
			div.find(".tab."+all_types[i]).hide();
		}else{
			div.find(".tab."+all_types[i]).show();
		}
	}
}

/**
 * Parse Tag-Link into Tag JSON Object
 * @param Object HTMLElement that represents the Tag
 */
function _parseTagLink(a){
	var matches = a.attr("id").match(/-(.*?)-(\d+)$/);
	return {
		id: parseInt(matches[2]),
		type: matches[1],
		name: a.html()
	}
}
/**
 * Create a HTMLElement based on a passed Tag Object
 * @param JSON Tag Object
 * @param String Entity (user,search,target)
 * @param String NodeName to use
 */
function _makeTagHTML(tag, entity, nodeName){
	nodeName = typeof(nodeName)=="undefined" ? "li" : nodeName;
	var t = $('<' + nodeName + ' class="tag_box" id="'+entity+'tag-'+tag.type+'-'+tag.id+'" />');
	t.append('<input type="hidden" name="tags[]" value="'+tag.id+'" />');
	t.append(tag.name);
	t.append('<a href="javascript:void(0)" onclick="$(this).parent().remove()" class="delete">x</a>');
	return t;
}

/**
 * Add a tag to the Article (write article page)
 * User searches tags, they're displayed in tabbed dialog, he clicks on one
 * and then this function
 * @param jQuery-Object Tag HTML Object
 */
function TagAdd2Article(a){
	var tag = _parseTagLink(a);
	if(!$("#articletag-"+tag.type+"-"+tag.id).length){
		var t = _makeTagHTML(tag,'article');
		t.hide();
		$("#article-tags").append(t);
		t.fadeIn("slow");
	}
}
/**
 * Add a tag to the UserTags list
 */
function TagsUser(){
	$.ajax({
		url: TAG_SEARCH_URL,
		data: {user: true},
		success: function(data,status,req){
			var div = $('<div />');
			var inpt = $('<input type="text" class="user-search-tags search-tags" />').appendTo(div);
			var form = $('<form action="javascript:void(0)" onsubmit="TagsUserSave(this)" method="post" />').appendTo(div);
			var tags = eval('('+data+')');
			
			form.append('<div class="user-tags user-tags-subject"><ul /></div>');
			form.append('<div class="user-tags user-tags-people"><ul /></div>');
			form.append('<div class="user-tags user-tags-geo"><ul /></div>');
			form.append('<input type="submit" value="Save" class="submit" />');
			form.append('<div class="message user-tags-message" />');
			if(tags.length > 0){
				for(var i=0; i<tags.length; i++){
					form.find('.user-tags-'+tags[i].type+' ul').append(_makeTagHTML(tags[i],'user'));
				}
			}
			
			div.dialog({
				width:660,
				height:400,
				modal: true,
				title: "My Tags",
				resizable:false,
				beforeClose: function(){
					div.remove()
				}
			});
			InitTagsBox("input.user-search-tags", "input", TagUserAdd);
		}
	})
}
function TagUserAdd(a){
	var tag = _parseTagLink(a);
	if(!$("#usertag-"+tag.type+"-"+tag.id).length){
		var t = _makeTagHTML(tag,'user');
		t.hide();
		$(".user-tags-"+tag.type+" ul").append(t);
		t.fadeIn("slow");
	}
}
function TagsUserSave(form){
	form = $(form);
	$.ajax({
		url: TAG_USER_SAVE_URL,
		data: form.serialize(),
		beforeSend: function(){
			form.find(".submit").val("Loading...").attr("disabled","disabled");
		},
		complete:function(req){
			form.find(".submit").val("Save").removeAttr("disabled");
			var msg = form.find(".message");
			msg.html(req.responseText);
			if(req.status==200){
				msg.removeClass("error");
			}else{
				msg.addClass("error");
			}
			msg.fadeIn(500, "", function(){
				setTimeout(function(){
					msg.fadeOut("slow");
				}, 3000);
			});
		}
	});
}